﻿using IMServer.Models;
using MongoDB.Driver;
using IMServer.Database;
using IMServer.Models.Message;

namespace IMServer.Services
{
    public class MessageBoxDbService
    {
        private static readonly MessageBoxDbService _instance = new MessageBoxDbService();
        private static IMongoCollection<MessageBox>? _messageBoxesCollection;

        // 私有构造函数
        private MessageBoxDbService()
        {
            try
            {
                Console.WriteLine("Starting _messageBoxesCollection initialization...");
                var dbContext = MongoDBContext.Instance;
                _messageBoxesCollection = dbContext.MessageBoxes;

                if (_messageBoxesCollection == null)
                    throw new InvalidOperationException("Failed to initialize messageBoxes collection");

                // 创建索引
                var indexOptions = new CreateIndexOptions { Unique = true };
                var indexKeys = Builders<MessageBox>.IndexKeys.Ascending(static x => x.UserId);
                _ = _messageBoxesCollection.Indexes.CreateOne(
                    new CreateIndexModel<MessageBox>(indexKeys, indexOptions));

                Console.WriteLine("MessageBoxDbService initialized successfully");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error initializing MessageDbService: {ex.Message}");
                throw;
            }
        }

        public static MessageBoxDbService Instance => _instance;
        
        public async Task<bool> CreateMessageBoxAsync(string userId)
        {
            if (_messageBoxesCollection == null)
                throw new InvalidOperationException("Database not initialized");

            try
            {
                var messageBox = new MessageBox
                {
                    UserId = userId,
                    Messages = new List<BaseMessage>(),
                    LastReadTime = DateTime.UtcNow,
                    UnreadCount = 0
                };

                await _messageBoxesCollection.InsertOneAsync(messageBox);
                return true;
            }
            catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
            {
                // 如果消息箱已存在，返回 true
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public async Task<bool> InsertMessageAsync(string userId, BaseMessage message)
        {
            if (_messageBoxesCollection == null)
                throw new InvalidOperationException("Database not initialized");

            var update = Builders<MessageBox>.Update
                .AddToSet(x => x.Messages, message)
                .Inc(x => x.UnreadCount, 1);

            var options = new UpdateOptions { IsUpsert = true };

            var result = await _messageBoxesCollection.UpdateOneAsync(
                x => x.UserId == userId,
                update,
                options);
            
            return result.ModifiedCount > 0 || result.UpsertedId != null;
        }
        
        public async Task<(List<BaseMessage> Messages, int UnreadCount)> GetUnreadMessagesAsync(string userId)
        {
            if (_messageBoxesCollection == null)
                throw new InvalidOperationException("Database not initialized");

            try
            {
                // 1. 获取用户的消息箱
                var messageBox = await _messageBoxesCollection
                    .Find(x => x.UserId == userId)
                    .FirstOrDefaultAsync();

                if (messageBox == null)
                    return (new List<BaseMessage>(), 0);

                // 2. 获取所有未读消息
                var unreadMessages = messageBox.Messages
                    .Where(m => !m.IsRead)
                    .ToList();

                // 3. 标记这些消息为已读
                if (unreadMessages.Any())
                {
                    var update = Builders<MessageBox>.Update
                        .Set(x => x.LastReadTime, DateTime.UtcNow)
                        .Set(x => x.UnreadCount, 0)
                        .Set("Messages.$[].IsRead", true);

                    await _messageBoxesCollection.UpdateOneAsync(
                        x => x.UserId == userId,
                        update);
                }

                return (unreadMessages, unreadMessages.Count);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error getting unread messages: {ex.Message}");
                return (new List<BaseMessage>(), 0);
            }
        }
    }
}
